﻿using System;
using UniRx.InternalUtil;

namespace UniRx
{
	// Token: 0x02000412 RID: 1042
	public class AsyncReactiveCommand<T> : IAsyncReactiveCommand<T>
	{
		// Token: 0x06001566 RID: 5478 RVA: 0x0005F1C1 File Offset: 0x0005D5C1
		public AsyncReactiveCommand()
		{
			this.canExecuteSource = new ReactiveProperty<bool>(true);
			this.canExecute = this.canExecuteSource;
		}

		// Token: 0x06001567 RID: 5479 RVA: 0x0005F1F8 File Offset: 0x0005D5F8
		public AsyncReactiveCommand(IObservable<bool> canExecuteSource)
		{
			this.canExecuteSource = new ReactiveProperty<bool>(true);
			this.canExecute = this.canExecute.CombineLatest(canExecuteSource, (bool x, bool y) => x && y).ToReactiveProperty<bool>();
		}

		// Token: 0x06001568 RID: 5480 RVA: 0x0005F261 File Offset: 0x0005D661
		public AsyncReactiveCommand(IReactiveProperty<bool> sharedCanExecute)
		{
			this.canExecuteSource = sharedCanExecute;
			this.canExecute = sharedCanExecute;
		}

		// Token: 0x1700019C RID: 412
		// (get) Token: 0x06001569 RID: 5481 RVA: 0x0005F28D File Offset: 0x0005D68D
		public IReadOnlyReactiveProperty<bool> CanExecute
		{
			get
			{
				return this.canExecute;
			}
		}

		// Token: 0x1700019D RID: 413
		// (get) Token: 0x0600156A RID: 5482 RVA: 0x0005F295 File Offset: 0x0005D695
		// (set) Token: 0x0600156B RID: 5483 RVA: 0x0005F29D File Offset: 0x0005D69D
		public bool IsDisposed { get; private set; }

		// Token: 0x0600156C RID: 5484 RVA: 0x0005F2A8 File Offset: 0x0005D6A8
		public IDisposable Execute(T parameter)
		{
			if (this.canExecute.Value)
			{
				this.canExecuteSource.Value = false;
				Func<T, IObservable<Unit>>[] data = this.asyncActions.Data;
				if (data.Length == 1)
				{
					try
					{
						IObservable<Unit> source = data[0](parameter) ?? Observable.ReturnUnit();
						return source.Finally(delegate
						{
							this.canExecuteSource.Value = true;
						}).Subscribe<Unit>();
					}
					catch
					{
						this.canExecuteSource.Value = true;
						throw;
					}
				}
				IObservable<Unit>[] array = new IObservable<Unit>[data.Length];
				try
				{
					for (int i = 0; i < data.Length; i++)
					{
						array[i] = (data[i](parameter) ?? Observable.ReturnUnit());
					}
				}
				catch
				{
					this.canExecuteSource.Value = true;
					throw;
				}
				return Observable.WhenAll(array).Finally(delegate
				{
					this.canExecuteSource.Value = true;
				}).Subscribe<Unit>();
			}
			return Disposable.Empty;
		}

		// Token: 0x0600156D RID: 5485 RVA: 0x0005F3B8 File Offset: 0x0005D7B8
		public IDisposable Subscribe(Func<T, IObservable<Unit>> asyncAction)
		{
			object obj = this.gate;
			lock (obj)
			{
				this.asyncActions = this.asyncActions.Add(asyncAction);
			}
			return new AsyncReactiveCommand<T>.Subscription(this, asyncAction);
		}

		// Token: 0x04000C51 RID: 3153
		private ImmutableList<Func<T, IObservable<Unit>>> asyncActions = ImmutableList<Func<T, IObservable<Unit>>>.Empty;

		// Token: 0x04000C52 RID: 3154
		private readonly object gate = new object();

		// Token: 0x04000C53 RID: 3155
		private readonly IReactiveProperty<bool> canExecuteSource;

		// Token: 0x04000C54 RID: 3156
		private readonly IReadOnlyReactiveProperty<bool> canExecute;

		// Token: 0x02000413 RID: 1043
		private class Subscription : IDisposable
		{
			// Token: 0x06001571 RID: 5489 RVA: 0x0005F430 File Offset: 0x0005D830
			public Subscription(AsyncReactiveCommand<T> parent, Func<T, IObservable<Unit>> asyncAction)
			{
				this.parent = parent;
				this.asyncAction = asyncAction;
			}

			// Token: 0x06001572 RID: 5490 RVA: 0x0005F448 File Offset: 0x0005D848
			public void Dispose()
			{
				object gate = this.parent.gate;
				lock (gate)
				{
					this.parent.asyncActions = this.parent.asyncActions.Remove(this.asyncAction);
				}
			}

			// Token: 0x04000C57 RID: 3159
			private readonly AsyncReactiveCommand<T> parent;

			// Token: 0x04000C58 RID: 3160
			private readonly Func<T, IObservable<Unit>> asyncAction;
		}
	}
}
